home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / motif / ostencil.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  10KB  |  338 lines

  1. /*
  2.  * Copyright (c) 1993-94, Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that the name of Silicon Graphics may not be used in any advertising or
  7.  * publicity relating to the software without the specific, prior written
  8.  * permission of Silicon Graphics.
  9.  *
  10.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  11.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  12.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  13.  *
  14.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  15.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
  16.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
  17.  * POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN
  18.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  19.  *
  20.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  21.  */
  22. /*----------------------------------------------------------------------------
  23.  *
  24.  * ostencil.c : openGL (motif) example showing how to use stencils
  25.  *
  26.  * Author : Yusuf Attarwala
  27.  *          SGI - Applications
  28.  * Date   : Mar 93
  29.  *
  30.  *    note : the main intent of this program is to demo the stencil
  31.  *           plane functionality, hence the rendering is kept
  32.  *           simple (wireframe).
  33.  *
  34.  *    press  left   button for animation
  35.  *    press  middle button to turn OFF stenciling
  36.  *    press  right  button to turn ON  stenciling
  37.  *
  38.  *---------------------------------------------------------------------------*/
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42.  
  43. #include <Xm/Xm.h> 
  44. #include <Xm/Frame.h>               /* for frame widgets */
  45. #include <Xm/Form.h>               /* for frame widgets */
  46. #include <X11/keysym.h>             /* keyboard translations */
  47. #include <X11/StringDefs.h>
  48.  
  49. #include <GL/gl.h>                  /* gl includes */
  50. #include <GL/glu.h>                 /* utility library includes */
  51. #include <GL/GLwMDrawA.h>           /* include for the drawing area widget */
  52.  
  53. static int stencilOn = 1;
  54.  
  55. /* function declarations */
  56.  
  57. void 
  58.     createToplevel(void),
  59.     drawScene(void),
  60.     setMatrix(void),
  61.     setEtchingArea(void),
  62.     initLightAndMaterial(void),
  63.     animation(void),
  64.     exposeCB(Widget,XtPointer,XtPointer),
  65.     resizeCB(Widget,XtPointer,XtPointer),
  66.     initCB(Widget,XtPointer,XtPointer),
  67.     inputCB(Widget,XtPointer,XtPointer);
  68.  
  69.  
  70. /* global variables */
  71.             
  72. Display       *display;             /* current display */
  73. XtAppContext  appContext;           /* X application context */
  74. float         ax,ay,az;             /* angles for animation */
  75. GLUquadricObj *quadObj;             /* used in drawscene */
  76.  
  77. Widget        toplevel,       /* toplevel shell */
  78.               glw;            /* current widget */
  79.              
  80. GLXContext    glxc;           /* current glx context */
  81.  
  82. Arg args[20];
  83. int acnt;
  84.  
  85. void 
  86. main(int argc, char** argv)
  87. {
  88.     XtToolkitInitialize();
  89.     appContext = XtCreateApplicationContext();
  90.     display    = XtOpenDisplay(appContext, NULL, "Ostencil","ostencil",NULL,0,
  91.                               &argc,argv);
  92.     if (!display) {
  93.         printf("%s : Unable to open display\n",argv[0]);
  94.         exit(0);
  95.     }
  96.  
  97.     printf("\n---------------------------------------------\n");
  98.     printf("OpenGL stencil example \n\n");
  99.     printf("Press:  left   button for animation\n\
  100.         middle button to turn OFF stenciling\n\
  101.         right  button to turn ON  stenciling (default)\n");
  102.  
  103.     quadObj = gluNewQuadric ();   /* this will be used in drawScene */
  104.     createToplevel();             /* create widget hierarchy */
  105.     XtAppMainLoop(appContext);    /* loop forever */
  106. }
  107.  
  108.  
  109. void
  110. createToplevel(void)
  111. {
  112.     Widget frame;
  113.  
  114.     acnt = 0;
  115.     XtSetArg(args[acnt],XmNminHeight, 300);acnt++;
  116.     XtSetArg(args[acnt],XmNminWidth,  300);acnt++;
  117.     XtSetArg(args[acnt],XmNminAspectX,  1);acnt++;
  118.     XtSetArg(args[acnt],XmNminAspectY,  1);acnt++;
  119.     XtSetArg(args[acnt],XmNmaxAspectX,  1);acnt++;
  120.     XtSetArg(args[acnt],XmNmaxAspectY,  1);acnt++;
  121.     toplevel  = XtAppCreateShell("openGL stencil","ostencil",
  122.                                   applicationShellWidgetClass,
  123.                                   display,args,acnt);
  124.  
  125.     /* create a frame to hold glx widget */
  126.     frame   = XtVaCreateManagedWidget("frame", 
  127.                   xmFrameWidgetClass, toplevel, 
  128.                   NULL);
  129.  
  130.     /* create a double buffer widget, in rgb mode and manage it */
  131.     acnt = 0;
  132.     XtSetArg(args[acnt], GLwNrgba,               TRUE); acnt++;
  133.     XtSetArg(args[acnt], GLwNdoublebuffer,       TRUE); acnt++;
  134.     XtSetArg(args[acnt], GLwNstencilSize,        1); acnt++;
  135.     XtSetArg(args[acnt], GLwNallocateBackground, TRUE); acnt++;
  136.     glw = GLwCreateMDrawingArea(frame, "glw", args, acnt);
  137.     XtManageChild(glw);
  138.  
  139.     /* register callbacks */
  140.     XtAddCallback(glw, GLwNginitCallback,  initCB,   NULL);
  141.  
  142.     /* realize widget hierarchy */
  143.     XtRealizeWidget(toplevel);
  144.  
  145.     /*
  146.     initLightAndMaterial();
  147.     */
  148.  
  149.     /* additional callbacks */
  150.     XtAddCallback(glw, GLwNexposeCallback, exposeCB, NULL);
  151.     XtAddCallback(glw, GLwNresizeCallback, resizeCB, NULL);
  152.     XtAddCallback(glw, GLwNinputCallback,  inputCB,  NULL);
  153.  
  154. }
  155.  
  156. static float p0[] = {-5.0,-5.0,0.0};
  157. static float p1[] = {5.0,-5.0,0.0};
  158. static float p2[] = {5.0,5.0,0.0};
  159. static float p3[] = {-5.0,5.0,0.0};
  160.  
  161. void
  162. setEtchingArea()
  163. {
  164.     /* create a rectangle in the center where the stencil
  165.        bits are set */
  166.  
  167.     glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
  168.     glClearStencil(0);
  169.     glClear(GL_STENCIL_BUFFER_BIT);
  170.  
  171.     glEnable(GL_STENCIL_TEST);
  172.     glStencilFunc(GL_ALWAYS,1,1);
  173.     glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
  174.     glBegin(GL_POLYGON);
  175.         glVertex3fv(p0);
  176.         glVertex3fv(p1);
  177.         glVertex3fv(p2);
  178.         glVertex3fv(p3);
  179.     glEnd();
  180.     
  181.     glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
  182.     glDisable(GL_STENCIL_TEST);
  183. }
  184.  
  185. void
  186. drawScene(void)
  187. {
  188.  
  189.     glClearColor(0.3, 0.3, 0.3, 0.0);
  190.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  191.  
  192.     /* draw the etched area in a different color for visual clue */
  193.     /* note that the stencil test is disabled at this point */
  194.  
  195.     glColor3f (0.0, 0.0, 0.0);
  196.     glBegin(GL_POLYGON);
  197.         glVertex3fv(p0);
  198.         glVertex3fv(p1);
  199.         glVertex3fv(p2);
  200.         glVertex3fv(p3);
  201.     glEnd();
  202.  
  203.     if (stencilOn) glEnable(GL_STENCIL_TEST);
  204.     glPushMatrix();
  205.     gluQuadricDrawStyle (quadObj, GLU_LINE);
  206.  
  207.     glRotatef (ax,1.0,0.0,0.0);
  208.     glRotatef (-ay,0.0, 1.0, 0.0);
  209.  
  210.     /* draw a cone where the stencil is not set to 1 */
  211.     glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
  212.     glStencilFunc(GL_NOTEQUAL,1,1);
  213.     glColor3f (1.0, 1.0, 0.0);
  214.     gluCylinder (quadObj, 2.0,5.0,10.0,20,8);  /* draw a cone */
  215.  
  216.     /* draw a cone (in different color) where the stencil is set to 1 */
  217.     glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
  218.     glStencilFunc(GL_EQUAL,1,1);
  219.     glColor3f (0.0, 1.0, 1.0);
  220.     gluCylinder (quadObj, 2.0,5.0,10.0,20,8);  /* draw a cone */
  221.  
  222.     glPopMatrix();
  223.     if (stencilOn) glDisable(GL_STENCIL_TEST);
  224.  
  225.     glFlush();
  226.     glXSwapBuffers(XtDisplay(glw), XtWindow(glw));
  227.  
  228. }
  229.  
  230. void
  231. setMatrix(void)
  232. {
  233.     glMatrixMode(GL_PROJECTION);
  234.     glLoadIdentity();
  235.     glOrtho(-12.0,12.0,-12.0,12.0,-12.0,12.0);
  236.     glMatrixMode(GL_MODELVIEW);
  237.     glLoadIdentity();
  238. }
  239.  
  240. void
  241. animation(void)
  242. {
  243.     register int i;
  244.     /* animate the cone */
  245.  
  246.     for (i=0;i<60;i++) {
  247.         ax += 5.0;
  248.         ay -= 2.0;
  249.         az += 5.0;
  250.         if (ax >= 360)  ax = 0.0;
  251.         if (ay <= -360) ay = 0.0;
  252.         if (az >= 360)  az = 0.0;
  253.         drawScene();
  254.     }
  255. }
  256.  
  257. void 
  258. inputCB(Widget w, XtPointer client_data, XtPointer call)
  259. {
  260.     char            string[31];
  261.     XComposeStatus  composeStatus;
  262.     KeySym keysym;
  263.     GLwDrawingAreaCallbackStruct *call_data;
  264.  
  265.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  266.  
  267.     switch(call_data->event->type) {
  268.     case ButtonPress:
  269.         switch (call_data->event->xbutton.button) {
  270.         case Button1:
  271.         animation();
  272.             break;
  273.         case Button2 :
  274.         stencilOn = 0;
  275.         drawScene();
  276.             break;
  277.         case Button3 :
  278.         stencilOn = 1;
  279.         drawScene();
  280.             break;
  281.         }
  282.         break;
  283.     case KeyPress :
  284.         XLookupString((XKeyEvent *)call_data->event,string,
  285.                       30,&keysym,&composeStatus);
  286.         switch(keysym) {
  287.         case XK_Escape :
  288.             exit(0);
  289.             break;
  290.         }
  291.     break;
  292.     default:
  293.         break;
  294.     }
  295. }
  296.  
  297. void 
  298. resizeCB(Widget w, XtPointer client_data, XtPointer call)
  299. {
  300.     GLwDrawingAreaCallbackStruct *call_data;
  301.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  302.  
  303.     GLwDrawingAreaMakeCurrent(w, glxc);
  304.     glViewport(0, 0, call_data->width, call_data->height);
  305.     setMatrix();
  306.  
  307.     setEtchingArea();    /* using stencils */
  308.     drawScene();
  309. }
  310.  
  311. void 
  312. exposeCB(Widget w, XtPointer client_data, XtPointer call)
  313. {
  314.     GLwDrawingAreaCallbackStruct *call_data;
  315.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  316.  
  317.  
  318.     GLwDrawingAreaMakeCurrent(w, glxc);
  319.     glViewport(0, 0, call_data->width, call_data->height);
  320.     drawScene();
  321. }
  322.  
  323. void
  324. initCB(Widget w, XtPointer client_data, XtPointer call)
  325. {
  326.     XVisualInfo *vi;
  327.  
  328.     XtSetArg(args[0], GLwNvisualInfo, &vi);
  329.     XtGetValues(w, args, 1);
  330.  
  331.     glxc = glXCreateContext(XtDisplay(w), vi, 0, GL_TRUE);
  332.  
  333.     ax = 10.0;
  334.     ay = -10.0;
  335.     az = 0.0;
  336. }
  337.  
  338.